package com.whale.nangua.pumpkingobang.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;


import com.example.wuziqi.R;
import com.whale.nangua.pumpkingobang.aty.RenjiGameAty;
import com.whale.nangua.pumpkingobang.bean.Piece;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.Stack;

public class RenjiGobangView extends View {
    protected static int GRID_SIZE = 16;    //设置为国际标准
    protected static int GRID_WIDTH = 42; // 棋盘格的宽度
    protected static int CHESS_DIAMETER = 37; // 棋的直径
    protected static int mStartX;// 棋盘定位的左上角X
    protected static int mStartY;// 棋盘定位的左上角Y

    private int comCount = 0;
    private int playerCount = 0;
    private boolean ready = true;
    private static int[][] mGridArray; // 网格
    private int gBoard[][] = new int[15][15];
    private final int M_SIZE = 15;
    //计分板
    private final int WIN5 = 100000;//连5
    private final int ALIVE4 = 10000;//活4
    private final int ALIVE3 = 1000;//活3
    private final int DIE4 = 1000;//冲4
    private final int ALIVE2 = 100;//活2
    private final int DIE3 = 100;//冲3
    private final int DIE2 = 10;//冲2
    private final int ALIVE1 = 10;//活1
    
    
    private Stack<String> storageArray;


    int wbflag = 1; //该下白棋了=2，该下黑棋了=1. 这里先下黑棋（黑棋以后设置为机器自动下的棋子）
    int mLevel = 1; //游戏难度
    int mWinFlag = 0;
    private final int BLACK = 1;
    private final int WHITE = 2;


    //private TextView mStatusTextView; //  根据游戏状态设置显示的文字
    private TextView mStatusTextView; //  根据游戏状态设置显示的文字

    private Bitmap btm1;
    private final Paint mPaint = new Paint();

    CharSequence mText;
    CharSequence STRING_WIN = "白棋赢啦!  ";
    CharSequence STRING_LOSE = "黑棋赢啦!  ";
    CharSequence STRING_EQUAL = "和棋！  ";

    public RenjiGobangView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setFocusable(true);
        this.setFocusableInTouchMode(true);

        init();
    }

    //按钮监听器
    MyButtonListener myButtonListener;

    // 初始化黑白棋的Bitmap
    public void init() {
        cunchusandianArraylist = new ArrayList<>();
        storageArray = new Stack<>();
        myButtonListener = new MyButtonListener();
        wbflag = BLACK; //初始为先下黑棋
        mWinFlag = 0; //清空输赢标志。
        mGridArray = new int[GRID_SIZE - 1][GRID_SIZE - 1];


        Bitmap bitmap = Bitmap.createBitmap(CHESS_DIAMETER, CHESS_DIAMETER, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Resources r = this.getContext().getResources();

    }

    //设置显示的textView
    public void setTextView(TextView tv) {
        mStatusTextView = tv;
        //mStatusTextView.setVisibility(View.INVISIBLE);
    }

    //悔棋按钮
    Button huiqi;
    //刷新那妞
    Button refresh;

    //设置两个按钮
    public void setButtons(Button huiqi, Button refresh) {
        this.huiqi = huiqi;
        this.refresh = refresh;
        huiqi.setOnClickListener(myButtonListener);
        refresh.setOnClickListener(myButtonListener);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        // 动态计算GRID_WIDTH，使棋盘宽度为屏幕宽度的80%
        float aspectRatio = 0.8f; // 可以根据需要调整这个比例
        int boardSize = (int) (w * aspectRatio);
        GRID_WIDTH = boardSize / GRID_SIZE;

        // 计算起始坐标，使棋盘居中显示
        mStartX = (w - boardSize) / 2;
        mStartY = (h - boardSize) / 2;
    }

    public void setWinListner(RenjiGameAty renjiGameAty) {
        onWinListener = renjiGameAty;
    }

    OnWinListener onWinListener;

    public interface OnWinListener{
        void onWin(int i );
    }

    /**
     * 点下出现棋子
     *
     * @param event
     * @return
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int x;
        int y;
        float x0 = GRID_WIDTH - (event.getX() - mStartX) % GRID_WIDTH;
        float y0 = GRID_WIDTH - (event.getY() - mStartY) % GRID_WIDTH;
        if (x0 < GRID_WIDTH / 2) {
            x = (int) ((event.getX() - mStartX) / GRID_WIDTH);
        } else {
            x = (int) ((event.getX() - mStartX) / GRID_WIDTH) - 1;
        }
        if (y0 < GRID_WIDTH / 2) {
            y = (int) ((event.getY() - mStartY) / GRID_WIDTH);
        } else {
            y = (int) ((event.getY() - mStartY) / GRID_WIDTH) - 1;
        }

        if ((x >= 0 && x < GRID_SIZE - 1)
                && (y >= 0 && y < GRID_SIZE - 1)) {
            if (mGridArray[x][y] == 0) {
                if (wbflag == BLACK) {

                    if(!ready){
                        return true;
                    }
                    putChess(x, y, BLACK);
                    playerCount++;
                    ready=true;
                    //这个时候电脑自动下白棋
                    //根据难度选择对应的电脑智商
                    new ComputerMoveTask(x, y, WHITE).execute();

                    //this.mGridArray[x][y] = 1;
                    if (checkWin(BLACK)) { //如果是黑棋赢了
                        mText = STRING_LOSE;
                        showTextView(mText);
                        onWinListener.onWin(1);
                    } else if (checkFull()) {//如果棋盘满了
                        mText = STRING_EQUAL;
                        showTextView(mText);
                    }
                    wbflag = BLACK;//然后下一步接着下黑棋
                } else if (wbflag == WHITE) {
                    putChess(x, y, WHITE);
                    //这个时候电脑自动下黑棋
                    //根据难度选择对应的电脑智商
                    new ComputerMoveTask(x, y, WHITE).execute();

                    //this.mGridArray[x][y] = 2;
                    if (checkWin(WHITE)) {
                        mText = STRING_WIN;
                        showTextView(mText);
                        onWinListener.onWin(2);
                    } else if (checkFull()) {//如果棋盘满了
                        mText = STRING_EQUAL;
                        showTextView(mText);
                    }

                    wbflag = WHITE;//然后下一步接着下白棋
                }
            }
        }

        this.invalidate();
        return true;

    }

    private class ComputerMoveTask extends AsyncTask<Integer, Void, Void> {
        private int x;
        private int y;
        private int color;

        public ComputerMoveTask(int x, int y, int color) {
            this.x = x;
            this.y = y;
            this.color = color;
        }

        @Override
        protected Void doInBackground(Integer... params) {
            // 根据不同难度调用对应的电脑下棋方法，这里假设当前难度为nandu变量表示
            if (nandu == 1) {
                naocanautomatic(x, y, color);
            } else if (nandu == 2) {
                normalautomatic(x, y, color);
            } else {
                chaonanautomatic(x, y, color);
            }
            comCount++;
            ready=true;
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            // 电脑下棋逻辑执行完后，如果需要额外处理（比如判断是否满盘、是否赢棋等），在这里添加代码
            if (checkFull()) {
                mText = STRING_EQUAL;
                showTextView(mText);
            }
            // 最后触发一次重绘，显示电脑下棋后的整个棋盘状态
            invalidate();
        }
    }
    /**
     * 判断是否已经下过
     *
     * @param templist
     */
    private void panduanshifouyijingxiaguo(ArrayList<int[]> templist) {
        for (int i = 0; i < storageHadChess.size(); i++) {
            //如有重复，则删掉
            for (int j = 0; j < templist.size(); j++) {
                if (storageHadChess.get(i)[0] == templist.get(j)[0] && storageHadChess.get(i)[1] == templist.get(j)[1]) {
                    templist.remove(j);
                    //递归防止周围没有字落下时直接崩掉
                    if (templist.size() == 0) {
                        templist.add(new int[]{(int) (Math.random() * (GRID_SIZE - 2)), (int) (Math.random() * (GRID_SIZE - 2))});
                        //  Log.d("whalea", " " + (int) (Math.random() * (GRID_SIZE - 2)));
                        panduanshifouyijingxiaguo(templist);
                    }
                }
            }
        }
    }

    /**
     * 脑残模式自动下棋的电脑
     *
     * @param x
     * @param y     玩家下的坐标
     * @param Color 玩家下的棋的颜色    黑1白2
     *              <p/>
     *              x&y<GRID_SIZE - 1
     */
    private void naocanautomatic(int x, int y, int Color) {
        int[][] temp = {{x - 1, y - 1}, {x, y - 1}, {x + 1, y - 1}, {x - 1, y}, {x + 1, y}, {x - 1, y + 1}, {x, y + 1}, {x + 1, y + 1}};
        ArrayList<int[]> templist = new ArrayList<>();
        for (int i = 0; i < temp.length; i++) {
            if (temp[i][0] >= 0 && temp[i][0] < 13 && temp[i][1] >= 0 && temp[i][1] < 13) {
                templist.add(temp[i]);
            }
        }
        //判断是否已经下过
        panduanshifouyijingxiaguo(templist);

        int num = (int) (Math.random() * templist.size());
        int a = templist.get(num)[0];
        int b = templist.get(num)[1];
        putChess(a, b, Color);

    }

    ArrayList<String> cunchusandianArraylist;

    /**
     * 普通模式自动下棋的电脑
     * 黑1白2
     *
     * @param x
     * @param y
     * @param Color
     */
    private void normalautomatic(int x, int y, int Color) {
        int duishouColor = 0;//对手的颜色
        //根据我方颜色推测出对手颜色
        if (Color == 1) {
            duishouColor = 2;
        } else {
            duishouColor = 1;
        }
        //判断我方是否有3个连成一线了
        for (int i = 0; i < GRID_SIZE - 1; i++) //i表示列(根据宽度算出来的)
            for (int j = 0; j < GRID_SIZE - 1; j++) { //i表示行(根据高度算出来的)
                //检测横轴三个相连
                if ((((i + 3) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == Color) && (mGridArray[i + 1][j] == Color) && (mGridArray[i + 2][j] == Color)) ||
                        (((i + 3) < (GRID_SIZE - 1)) &&
                                (mGridArray[i][j] == duishouColor) && (mGridArray[i + 1][j] == duishouColor) && (mGridArray[i + 2][j] == duishouColor))) {
                    //如果有三个点相连了
                    //先判断是否已经测试过这三个点
                    boolean aa = false;
                    for (int p = 0; p < cunchusandianArraylist.size(); p++) {
                        String sandiantemp = cunchusandianArraylist.get(p);
                        String[] sandiantemps = sandiantemp.split(":");
                        //如果这三个点已经存在
                        if ((Integer.parseInt(sandiantemps[0]) == i) &&
                                (Integer.parseInt(sandiantemps[1]) == j) &&
                                (Integer.parseInt(sandiantemps[2]) == (i + 1)) &&
                                (Integer.parseInt(sandiantemps[3]) == j) &&
                                (Integer.parseInt(sandiantemps[4]) == (i + 2)) &&
                                (Integer.parseInt(sandiantemps[5]) == j)) {
                            aa = true;
                        }
                    }
                    if (aa == true) {

                    } else {
                        //在两边端点位置随机下一个
                        ifsangedianxianglian(i - 1, j, i + 3, j, Color);
                        cunchusandianArraylist.add(i + ":" + j + ":" + (i + 1) + ":" + j + ":" + (i + 2) + ":" + j);
                        return;
                    }
                }

                //纵轴3个相连
                if ((((j + 3) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == Color) && (mGridArray[i][j + 1] == Color) && (mGridArray[i][j + 2] == Color)) ||
                        (((j + 3) < (GRID_SIZE - 1)) &&
                                (mGridArray[i][j] == duishouColor) && (mGridArray[i][j + 1] == duishouColor) && (mGridArray[i][j + 2] == duishouColor))) {
                    //如果有三个点相连了
                    //先判断是否已经测试过这三个点
                    boolean aa = false;
                    for (int p = 0; p < cunchusandianArraylist.size(); p++) {
                        String sandiantemp = cunchusandianArraylist.get(p);
                        String[] sandiantemps = sandiantemp.split(":");
                        if ((Integer.parseInt(sandiantemps[0]) == i) &&
                                (Integer.parseInt(sandiantemps[1]) == j) &&
                                (Integer.parseInt(sandiantemps[2]) == i) &&
                                (Integer.parseInt(sandiantemps[3]) == (j + 1)) &&
                                (Integer.parseInt(sandiantemps[4]) == i) &&
                                (Integer.parseInt(sandiantemps[5]) == (j + 2))) {
                            aa = true;
                        }
                    }
                    if (aa == true) {

                    } else {
                        //在两边端点位置随机下一个
                        ifsangedianxianglian(i, j - 1, i, j + 3, Color);
                        cunchusandianArraylist.add(i + ":" + j + ":" + i + ":" + (j + 1) + ":" + i + ":" + (j + 2));
                        return;
                    }
                }

                //左上到右下3个相连
                if ((((j + 3) < (GRID_SIZE - 1)) && ((i + 3) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == Color) && (mGridArray[i + 1][j + 1] == Color) && (mGridArray[i + 2][j + 2] == Color)) ||
                        (((j + 3) < (GRID_SIZE - 1)) && ((i + 3) < (GRID_SIZE - 1)) &&
                                (mGridArray[i][j] == duishouColor) && (mGridArray[i + 1][j + 1] == duishouColor) && (mGridArray[i + 2][j + 2] == duishouColor))) {
                    //如果有三个点相连了
                    //先判断是否已经测试过这三个点
                    boolean aa = false;
                    for (int p = 0; p < cunchusandianArraylist.size(); p++) {
                        String sandiantemp = cunchusandianArraylist.get(p);
                        String[] sandiantemps = sandiantemp.split(":");
                        if ((Integer.parseInt(sandiantemps[0]) == i) &&
                                (Integer.parseInt(sandiantemps[1]) == j) &&
                                (Integer.parseInt(sandiantemps[2]) == (i + 1)) &&
                                (Integer.parseInt(sandiantemps[3]) == (j + 1)) &&
                                (Integer.parseInt(sandiantemps[4]) == (i + 2)) &&
                                (Integer.parseInt(sandiantemps[5]) == (j + 2))) {
                            aa = true;
                        }
                    }
                    if (aa == true) {

                    } else {
                        ifsangedianxianglian(i - 1, j - 1, i + 3, j + 3, Color);
                        cunchusandianArraylist.add(i + ":" + j + ":" + (i + 1) + ":" + (j + 1) + ":" + (i + 2) + ":" + (j + 2));
                        return;
                    }
                }

                //右上到左下3个相连
                if ((((i - 3) >= 0) && ((j + 3) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == Color) && (mGridArray[i - 1][j + 1] == Color) && (mGridArray[i - 2][j + 2] == Color)) ||
                        (((i - 3) >= 0) && ((j + 3) < (GRID_SIZE - 1)) &&
                                (mGridArray[i][j] == duishouColor) && (mGridArray[i - 1][j + 1] == duishouColor) && (mGridArray[i - 2][j + 2] == duishouColor))) {
                    //如果有三个点相连了
                    //先判断是否已经测试过这三个点
                    boolean aa = false;
                    for (int p = 0; p < cunchusandianArraylist.size(); p++) {
                        String sandiantemp = cunchusandianArraylist.get(p);
                        String[] sandiantemps = sandiantemp.split(":");
                        if ((Integer.parseInt(sandiantemps[0]) == i) &&
                                (Integer.parseInt(sandiantemps[1]) == j) &&
                                (Integer.parseInt(sandiantemps[2]) == (i - 1)) &&
                                (Integer.parseInt(sandiantemps[3]) == (j + 1)) &&
                                (Integer.parseInt(sandiantemps[4]) == (i - 2)) &&
                                (Integer.parseInt(sandiantemps[5]) == (j + 2))) {
                            aa = true;
                        }
                    }
                    if (aa == true) {

                    } else {
                        ifsangedianxianglian(i + 1, j - 1, i - 3, j + 3, Color);
                        cunchusandianArraylist.add(i + ":" + j + ":" + (i - 1) + ":" + j + 1 + ":" + (i - 2) + ":" + (j + 2));
                        return;
                    }
                }
            }
        int[][] temp = {{x - 1, y - 1}, {x, y - 1}, {x + 1, y - 1}, {x - 1, y}, {x + 1, y}, {x - 1, y + 1}, {x, y + 1}, {x + 1, y + 1}};
        ArrayList<int[]> templist = new ArrayList<>();
        for (int k = 0; k < temp.length; k++) {
            if (temp[k][0] >= 0 && temp[k][0] < 13 && temp[k][1] >= 0 && temp[k][1] < 13) {
                templist.add(temp[k]);
            }
            //判断是否已经下过
            panduanshifouyijingxiaguo(templist);
            int num = (int) (Math.random() * templist.size());
            int a = templist.get(num)[0];
            int b = templist.get(num)[1];
            putChess(a, b, Color);
            return;
        }
    }

    /**
     * 困难电脑の核心算法
     * 判断有三个点相连之后的操作
     */
    private void ifsangedianxianglian(int x, int y, int m, int n, int Color) {
        ArrayList<int[]> automaticChesslist = new ArrayList<>();
        automaticChesslist.add(new int[]{x, y});
        automaticChesslist.add(new int[]{m, n});
        panduanshifouyijingxiaguo(automaticChesslist);
        int randomindex = Math.round(automaticChesslist.size());
        int a = automaticChesslist.get(randomindex - 1)[0];
        int b = automaticChesslist.get(randomindex - 1)[1];
        putChess(a, b, Color);
    }


    private void chaonanautomatic(int x, int y, int Color){
        Piece p = new Piece();
        alphabeta(4,mGridArray,p);
        putChess(p.x, p.y, Color);
    }



    /**
     * 判断是否有s格内是否有棋子
     *
     * @param p
     * @return
     */
    private boolean has_neighbors(Piece p) {
        //设定判断距离
        int s = 2;
        //防止溢出
        for (int i = (p.x - s > 0 ? p.x - s : 0); i <= p.x + s && i < 15; i++)
            for (int j = (p.y - s > 0 ? p.y - s : 0); j <= p.y + s && j < 15; j++)
                if (0 != gBoard[i][j])
                    return true;
        return false;
    }

    /**
     * 通过计分板来打分
     *
     * @param number 连子的个数
     * @param empty  两端为空的个数
     * @return
     */
    private int score_table(int number, int empty) {
        if (number >= 5)
            return WIN5;
        else if (number == 4) {
            if (empty == 2)
                return ALIVE4;
            else if (empty == 1)
                return DIE4;
        } else if (number == 3) {
            if (empty == 2)
                return ALIVE3;
            else if (empty == 1)
                return DIE3;
        } else if (number == 2) {
            if (empty == 2)
                return ALIVE2;
            else if (empty == 1)
                return DIE2;
        } else if (number == 1 && empty == 2)
            return ALIVE1;
        return 0;
    }

    /**
     * 单点评估函数
     *
     * @param p          位置
     * @param chessColor 评价颜色
     * @return 得分
     */
    private int evaluate_point(Piece p, int chessColor) {
        int score = 0;
        int number, empty;
        int i, j;
        int x = p.x;
        int y = p.y;
        //横
        number = 0;
        empty = 0;
        for (i = x - 1; i >= 0 && i > x - 5; i--) {
            if (chessColor == gBoard[i][y])
                number++;
            else if (0 == gBoard[i][y]) {
                empty++;
                break;
            } else
                break;
        }
        for (i = x + 1; i < 15 && i < x + 5; i++) {
            if (chessColor == gBoard[i][y])
                number++;
            else if (0 == gBoard[i][y]) {
                empty++;
                break;
            } else
                break;
        }
        score += score_table(number + 1, empty);
        //竖
        number = 0;
        empty = 0;
        for (j = y - 1; j >= 0 && j > y - 5; j--) {
            if (chessColor == gBoard[x][j])
                number++;
            else if (0 == gBoard[x][j]) {
                empty++;
                break;
            } else
                break;
        }
        for (j = y + 1; j < 15 && j < y + 5; j++) {
            if (chessColor == gBoard[x][j])
                number++;
            else if (0 == gBoard[x][j]) {
                empty++;
                break;
            } else
                break;
        }
        score += score_table(number + 1, empty);
        //主对角线
        number = 0;
        empty = 0;
        for (i = x - 1, j = y - 1; i >= 0 && j >= 0 && i > x - 5 && j > y - 5; i--, j--) {
            if (chessColor == gBoard[i][j])
                number++;
            else if (0 == gBoard[i][j]) {
                empty++;
                break;
            } else
                break;
        }
        for (i = x + 1, j = y + 1; i < 15 && j < 15 && i < x + 5 && j < y + 5; i++, j++) {
            if (chessColor == gBoard[i][j])
                number++;
            else if (0 == gBoard[i][j]) {
                empty++;
                break;
            } else
                break;
        }
        score += score_table(number + 1, empty);
        //副对角线
        number = 0;
        empty = 0;
        for (i = x - 1, j = y + 1; i >= 0 && j < 15 && i > x - 5 && j < y + 5; i--, j++) {
            if (chessColor == gBoard[i][j])
                number++;
            else if (0 == gBoard[i][j]) {
                empty++;
                break;
            } else
                break;
        }
        for (i = x + 1, j = y - 1; i < 15 && j >= 0 && i < x + 5 && j > y - 5; i++, j--) {
            if (chessColor == gBoard[i][j])
                number++;
            else if (0 == gBoard[i][j]) {
                empty++;
                break;
            } else
                break;
        }
        score += score_table(number + 1, empty);
        return score;

    }

    /**
     * 全局评估函数
     *
     * @return
     */
    private int evaluate_situation() {
        int ComScore = 0;
        int RivalScore = 0;
        int i, j;
        int x, y;
        ArrayList<Integer> n = new ArrayList<>(M_SIZE + 1);
        //横
        for (i = 0; i < M_SIZE; i++) {
            for (j = 0; j < M_SIZE; j++)
                n.add(gBoard[j][i]);
            ComScore += count_score(n, WHITE);
            RivalScore += count_score(n, BLACK);
            n.clear();
        }
        //竖
        for (i = 0; i < M_SIZE; i++) {
            for (j = 0; j < M_SIZE; j++)
                n.add(gBoard[i][j]);
            ComScore += count_score(n, WHITE);
            RivalScore += count_score(n, BLACK);
            n.clear();
        }
        //主对角线
        for (i = 0; i < 15; i++) {
            for (x = i, y = 0; x < 15 && y < 15; x++, y++)
                n.add(gBoard[x][y]);
            ComScore += count_score(n, WHITE);
            RivalScore += count_score(n, BLACK);
            n.clear();
        }
        for (i = 1; i < 15; i++) {
            for (x = 0, y = i; x < 15 && y < 15; x++, y++)
                n.add(gBoard[x][y]);
            ComScore += count_score(n, WHITE);
            RivalScore += count_score(n, BLACK);
            n.clear();
        }
        //副对角线
        for (i = 0; i < 15; i++) {
            for (x = 0, y = i; x < 15 && y >= 0; x++, y--)
                n.add(gBoard[x][y]);
            ComScore += count_score(n, WHITE);
            RivalScore += count_score(n, BLACK);
            n.clear();
        }
        for (i = 1; i < 15; i++) {
            for (x = 14, y = i; x >= 0 && y < 15; x--, y++)
                n.add(gBoard[x][y]);
            ComScore += count_score(n, WHITE);
            RivalScore += count_score(n, BLACK);
            n.clear();
        }
        return ComScore - RivalScore;
    }

    /**
     * 评估一维数组的得分
     *
     * @param n
     * @param chessColor
     * @return
     */
    private int count_score(ArrayList<Integer> n, int chessColor) {
        int empty = 0;
        int number = 0;
        int scoretmp = 0;
        if (0 == n.get(0))
            empty++;
        else if (chessColor == n.get(0))
            number++;
        for (Integer i : n) {
            if (chessColor == i)
                number++;
            else if (0 == i) {
                if (number == 0)
                    empty = 1;
                else {
                    scoretmp += score_table(number, empty + 1);
                    empty = 1;
                    number = 0;
                }
            } else {
                scoretmp += score_table(number, empty);
                empty = 0;
                number = 0;
            }
        }
        scoretmp += score_table(number, empty);
        return scoretmp;
    }

    /**
     * 启发式搜索
     *
     * @return
     */
    private ArrayList<Piece> generate_point() {
        ArrayList<Piece> RivalFive = new ArrayList<Piece>();
        ArrayList<Piece> ComFour = new ArrayList<Piece>();
        ArrayList<Piece> RivalFour = new ArrayList<Piece>();
        ArrayList<Piece> ComDoubleThree = new ArrayList<Piece>();
        ArrayList<Piece> RivalDoubleThree = new ArrayList<Piece>();
        ArrayList<Piece> ComThree = new ArrayList<Piece>();
        ArrayList<Piece> RivalThree = new ArrayList<Piece>();
        ArrayList<Piece> ComTwo = new ArrayList<Piece>();
        ArrayList<Piece> RivalTwo = new ArrayList<Piece>();
        ArrayList<Piece> others = new ArrayList<Piece>();

        ArrayList<Piece> queue = new ArrayList<Piece>();
        for (int i = 0; i < 15; ++i) {
            for (int j = 0; j < 15; ++j) {
                Piece p = new Piece(i, j);
                if ((0 == gBoard[i][j]) && (has_neighbors(p))) {
                    int ComScore = evaluate_point(p, WHITE);
                    int RivalScore = evaluate_point(p, BLACK);
                    if (ComScore >= WIN5) {
                        queue.add(p);
                        return queue;
                    } else if (RivalScore >= WIN5)
                        RivalFive.add(p);
                    else if (ComScore >= ALIVE4)
                        ComFour.add(p);
                    else if (RivalScore >= ALIVE4)
                        RivalFour.add(p);
                    else if (ComScore >= ALIVE3 * 2)
                        ComDoubleThree.add(p);
                    else if (RivalScore >= ALIVE3 * 2)
                        RivalDoubleThree.add(p);
                    else if (ComScore >= ALIVE3)
                        ComThree.add(p);
                    else if (RivalScore >= ALIVE3)
                        RivalThree.add(p);
                    else if (ComScore >= ALIVE2)
                        ComTwo.add(p);
                    else if (RivalScore >= ALIVE2)
                        RivalTwo.add(p);
                    else
                        others.add(p);
                }
            }
        }
        if (RivalFive.size() > 0) {
            queue = RivalFive;
            return queue;
        }
        if (ComFour.size() > 0 || RivalFour.size() > 0) {
            queue = ComFour;
            queue.addAll(RivalFour);
            return queue;
        }
        if (ComDoubleThree.size() > 0 || RivalDoubleThree.size() > 0) {
            queue = ComDoubleThree;
            queue.addAll(RivalDoubleThree);
            return queue;
        }

        queue = ComThree;
        queue.addAll(RivalThree);
        queue.addAll(ComTwo);
        queue.addAll(RivalTwo);
        return queue;
    }

    /**
     * 搜索函数
     */
    private int alphabeta(int depth, int board[][], Piece p) {
        int best = -WIN5;
        ArrayList<Piece> option_queue = new ArrayList<Piece>(100);  //待选的空子队列
        ArrayList<Piece> sure_queue = new ArrayList<Piece>();        //最合适的下子位置
        //更新棋盘
        for (int i = 0; i < 15; i++)
            for (int j = 0; j < 15; j++)
                gBoard[i][j] = board[i][j];
        option_queue = generate_point();
        //System.out.println(option_queue.size());
        for (Piece i : option_queue) {
            int x = i.x;
            int y = i.y;
            gBoard[x][y] = WHITE;
            int tmp = min_alphabeta(depth - 1, i, -WIN5, WIN5);
            if (tmp == best) {
                sure_queue.add(i);
            }
            if (tmp > best) {
                best = tmp;
                sure_queue.clear();
                sure_queue.add(i);
            }
            gBoard[x][y] = 0;
        }
        //如果有多个解 取随机
        Random random = new Random();
        int k = random.nextInt(sure_queue.size());
        p.x = sure_queue.get(k).x;
        p.y = sure_queue.get(k).y;
        return best;
    }

    /**
     * alpha剪枝
     *
     * @param depth
     * @param alpha
     * @param beta
     * @return
     */
    private int min_alphabeta(int depth, Piece p, int alpha, int beta) {
        int res = evaluate_situation();
        //代表临时beta
        int best = WIN5;
        ArrayList<Piece> v = new ArrayList<>(50);
        //判断是否胜利
        if (depth <= 0 || p.is_win(gBoard, BLACK))
            return res;
        //生成待搜索序列
        v = generate_point();
        for (Piece i : v) {
            int x = i.x;
            int y = i.y;
            gBoard[x][y] = BLACK;
            int tmp = max_alphabeta(depth - 1, p, alpha, Math.min(best, beta));
            gBoard[x][y] = 0;
            best = Math.min(tmp, best);
            if (tmp < alpha)
                break;
        }
        return best;
    }

    /**
     * beta剪枝
     *
     * @param depth
     * @param alpha
     * @param beta
     * @return
     */
    private int max_alphabeta(int depth, Piece p, int alpha, int beta) {
        int res = evaluate_situation();
        //代表临时alpha
        int best = -WIN5;
        ArrayList<Piece> v = new ArrayList<>(50);
        //判断是否胜利
        if (depth <= 0 || p.is_win(gBoard, WHITE))
            return res;
        //生成待搜索序列
        v = generate_point();
        for (Piece i : v) {
            int x = i.x;
            int y = i.y;
            gBoard[x][y] = WHITE;
            int tmp = min_alphabeta(depth - 1, p, Math.max(best, alpha), beta);
            gBoard[x][y] = 0;
            best = Math.max(tmp, best);
            if (tmp > beta)
                break;
        }
        return best;
    }

    @Override
    public void onDraw(Canvas canvas) {
        //canvas.drawColor(Color.YELLOW);
        //先画实木背景
        Paint paintBackground = new Paint();
        Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.renji_qipang);
        canvas.drawBitmap(bitmap, null, new Rect(mStartX, mStartY, mStartX + GRID_WIDTH * GRID_SIZE, mStartY + GRID_WIDTH * GRID_SIZE), paintBackground);
        // 画棋盘
        Paint paintRect = new Paint();
        paintRect.setColor(Color.BLACK);
        paintRect.setStrokeWidth(2);
        paintRect.setStyle(Style.STROKE);
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                int mLeft = i * GRID_WIDTH + mStartX;
                int mTop = j * GRID_WIDTH + mStartY;
                int mRright = mLeft + GRID_WIDTH;
                int mBottom = mTop + GRID_WIDTH;
                canvas.drawRect(mLeft, mTop, mRright, mBottom, paintRect);
            }
        }
        //画棋盘的外边框
        paintRect.setStrokeWidth(4);
        canvas.drawRect(mStartX, mStartY, mStartX + GRID_WIDTH * GRID_SIZE, mStartY + GRID_WIDTH * GRID_SIZE, paintRect);

        //画棋子

        for (int i = 0; i < GRID_SIZE - 1; i++) {
            for (int j = 0; j < GRID_SIZE - 1; j++) {
                if (mGridArray[i][j] == BLACK) {
                    //通过圆形来画
                    {
                        Paint paintCircle = new Paint();
                        paintCircle.setAntiAlias(true);
                        paintCircle.setColor(Color.BLACK);
                        canvas.drawCircle(mStartX + (i + 1) * GRID_WIDTH, mStartY + (j + 1) * GRID_WIDTH, CHESS_DIAMETER / 2, paintCircle);
                    }

                } else if (mGridArray[i][j] == WHITE) {
                    //通过圆形来画
                    {
                        Paint paintCircle = new Paint();
                        paintCircle.setAntiAlias(true);
                        paintCircle.setColor(Color.WHITE);
                        canvas.drawCircle(mStartX + (i + 1) * GRID_WIDTH, mStartY + (j + 1) * GRID_WIDTH, CHESS_DIAMETER / 2, paintCircle);
                    }
                }
            }
        }
    }

    //储存已经下了的棋
    private ArrayList<int[]> storageHadChess = new ArrayList<>();


    public void putChess(int x, int y, int blackwhite) {
        storageHadChess.add(new int[]{x, y});
        mGridArray[x][y] = blackwhite;
        String temp = x + ":" + y;
        storageArray.push(temp);

    }


    /**
     * 检测是否赢了
     *
     * @param wbflag
     * @return
     */
    private boolean checkWin(int wbflag) {
        for (int i = 0; i < GRID_SIZE - 1; i++) //i表示列(根据宽度算出来的)
            for (int j = 0; j < GRID_SIZE - 1; j++) {//i表示行(根据高度算出来的)
                //检测横轴五个相连
                if (((i + 4) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == wbflag) && (mGridArray[i + 1][j] == wbflag) && (mGridArray[i + 2][j] == wbflag) && (mGridArray[i + 3][j] == wbflag) && (mGridArray[i + 4][j] == wbflag)) {
                    mWinFlag = wbflag;
                }

                //纵轴5个相连
                if (((j + 4) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == wbflag) && (mGridArray[i][j + 1] == wbflag) && (mGridArray[i][j + 2] == wbflag) && (mGridArray[i][j + 3] == wbflag) && (mGridArray[i][j + 4] == wbflag)) {
                    mWinFlag = wbflag;
                }

                //左上到右下5个相连
                if (((j + 4) < (GRID_SIZE - 1)) && ((i + 4) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == wbflag) && (mGridArray[i + 1][j + 1] == wbflag) && (mGridArray[i + 2][j + 2] == wbflag) && (mGridArray[i + 3][j + 3] == wbflag) && (mGridArray[i + 4][j + 4] == wbflag)) {
                    mWinFlag = wbflag;
                }

                //右上到左下5个相连
                if (((i - 4) >= 0) && ((j + 4) < (GRID_SIZE - 1)) &&
                        (mGridArray[i][j] == wbflag) && (mGridArray[i - 1][j + 1] == wbflag) && (mGridArray[i - 2][j + 2] == wbflag) && (mGridArray[i - 3][j + 3] == wbflag) && (mGridArray[i - 4][j + 4] == wbflag)) {
                    mWinFlag = wbflag;
                }
            }
        if (mWinFlag == wbflag) {
            return true;
        } else
            return false;
    }


    /**
     * 检查棋盘是否满了
     *
     * @return
     */
    public boolean checkFull() {
        int mNotEmpty = 0;
        for (int i = 0; i < GRID_SIZE - 1; i++)
            for (int j = 0; j < GRID_SIZE - 1; j++) {
                if (mGridArray[i][j] != 0) mNotEmpty += 1;
            }

        if (mNotEmpty == (GRID_SIZE - 1) * (GRID_SIZE - 1)) return true;
        else return false;
    }

    public void showTextView(CharSequence mT) {
        this.mStatusTextView.setText(mT);
        mStatusTextView.setVisibility(View.VISIBLE);
    }

    private int[] showtime;

    public void setShowTimeTextViewTime(int[] showtime) {
        this.showtime = showtime;
    }

    /**
     * 1简单难度
     * 2困难难度
     * 3超难难度
     *
     * @param i
     */
    public void setflag(int i) {
        nandu = i;
    }

    private static int nandu = 1;//默认为简单难度

    class MyButtonListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            int id = v.getId();//如果是悔棋
            if (id == R.id.btn1) {
                if (storageArray.size() == 0) {
                    Toast.makeText(getContext(), "开局并不能悔棋", Toast.LENGTH_SHORT).show();
                } else {
                    if (storageArray.size() == 2) {
                        storageArray.pop();
                        storageArray.pop();
                        mGridArray = new int[GRID_SIZE - 1][GRID_SIZE - 1];
                        invalidate();
                    } else {
                        String temp1 = storageArray.pop();
                        String[] temps = temp1.split(":");

                        int a = Integer.parseInt(temps[0]);
                        int b = Integer.parseInt(temps[1]);
                        mGridArray[a][b] = 0;

                        String temp2 = storageArray.pop();
                        String[] temps2 = temp2.split(":");

                        int c = Integer.parseInt(temps2[0]);
                        int d = Integer.parseInt(temps2[1]);
                        mGridArray[c][d] = 0;
                        invalidate();
                    }
                }
                //如果是刷新
            } else if (id == R.id.btn2) {
                setVisibility(View.VISIBLE);

                cunchusandianArraylist.clear();
                storageHadChess.clear();

                mStatusTextView.invalidate();
                init();
                invalidate();
                for (int i = 0; i < showtime.length; i++) {
                    showtime[i] = 0;
                }
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
                mStatusTextView.setText("人机模式 当前时间：" + simpleDateFormat.format(new Date()));
            }
        }
    }
}
